source('../env.R')
Using GitHub PAT from the git credential store.
Skipping install of 'clootl' from a github remote, the SHA1 (2ed1650b) has not changed since last install.
  Use `force = TRUE` to force installation

Create dataset

Load community data

communities = read_csv(filename(COMMUNITY_OUTPUT_DIR, 'communities_for_analysis.csv'))
Rows: 2428 Columns: 7── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (5): city_name, ebird_species_name, seasonal, presence, origin
dbl (2): city_id, relative_abundance_proxy
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
communities

Load trait data

traits = read_csv(filename(TAXONOMY_OUTPUT_DIR, 'traits_ebird.csv'))
Rows: 332 Columns: 10── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (5): ebird_species_name, habitat, trophic_level, trophic_niche, primary_lifestyle
dbl (5): beak_width, hwi, mass, habitat_density, migration
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(traits)
species_urban_response = communities %>% group_by(ebird_species_name) %>% summarise(mean_relative_abundance_proxy = mean(relative_abundance_proxy)) %>% left_join(traits)
Joining with `by = join_by(ebird_species_name)`
species_urban_response$is_urban = species_urban_response$mean_relative_abundance_proxy > 0
species_urban_response$ebird_species_name = str_replace(species_urban_response$ebird_species_name,' ', '_')
species_urban_response

Most urban species

species_urban_response %>% filter(mean_relative_abundance_proxy > 50)
species_urban_response %>% filter(mean_relative_abundance_proxy > 40)
species_urban_response %>% filter(mean_relative_abundance_proxy > 30)

Difference amongst urban and non-urban

species_urban_response %>% group_by(is_urban) %>% summarise(
  median_beak_width = median(beak_width),
  iqr_beak_width = IQR(beak_width),
  
  median_hwi = median(hwi),
  iqr_hwi = IQR(hwi),
  
  median_mass = median(mass),
  iqr_mass = IQR(mass),
  
  n = n()
)

Compare traits between urban and non-urban species

Gape Width

ggplot(species_urban_response, aes(x = is_urban, y = beak_width)) + geom_boxplot()

wilcox.test(beak_width ~ is_urban, species_urban_response)

    Wilcoxon rank sum test with continuity correction

data:  beak_width by is_urban
W = 1525, p-value = 0.3893
alternative hypothesis: true location shift is not equal to 0

There is not a significant response for the gape width between urban species and non urban species.

HWI

ggplot(species_urban_response, aes(x = is_urban, y = hwi)) + geom_boxplot()

wilcox.test(hwi ~ is_urban, species_urban_response)

    Wilcoxon rank sum test with continuity correction

data:  hwi by is_urban
W = 1213, p-value = 0.01492
alternative hypothesis: true location shift is not equal to 0

There is a significant response between urban and non-urban species

Mass

ggplot(species_urban_response, aes(x = is_urban, y = mass)) + geom_boxplot()

wilcox.test(mass ~ is_urban, species_urban_response)

    Wilcoxon rank sum test with continuity correction

data:  mass by is_urban
W = 1825, p-value = 0.5168
alternative hypothesis: true location shift is not equal to 0

There is not a significant response between species.

Phylogeny

Phylogentic response to relative abundance?

tree = read.tree(filename(TAXONOMY_OUTPUT_DIR, 'phylogeny.tre'))
tree_pruned = ladderize(drop.tip(tree, setdiff(tree$tip.label, species_urban_response$ebird_species_name)))
ggtree(tree_pruned, layout="fan")
Scale for y is already present.
Adding another scale for y, which will replace the existing scale.

columbidae_response <- species_urban_response$mean_relative_abundance_proxy
names(columbidae_response) <- species_urban_response$ebird_species_name

Is the a phylogenetic signal for our relative abundance proxy

col_ut_phylo_signal <- phylosig(tree_pruned, columbidae_response, method="lambda", test=TRUE)
col_ut_phylo_signal

Phylogenetic signal lambda : 0.46832 
logL(lambda) : -576.839 
LR(lambda=0) : 7.45324 
P-value (based on LR test) : 0.00633224 

Plot tree

species_urban_response$ebird_species_name_clean = gsub("_", " ", species_urban_response$ebird_species_name)

normalize <- function(x) (x - min(x)) / (max(x) - min(x)) * 5 + 1  # Scale to range [1, 6]
species_urban_response$beak_width_norm <- normalize(species_urban_response$beak_width)
species_urban_response$hwi_norm <- normalize(species_urban_response$hwi)
species_urban_response$mass_norm <- normalize(species_urban_response$mass)

g = ggtree(tree_pruned, layout="fan") %<+% species_urban_response + abundance_proxy_scale
Scale for y is already present.
Adding another scale for y, which will replace the existing scale.
g + 
  geom_fruit(geom = geom_point, mapping = aes(size = beak_width_norm), fill = beak_width_colour, colour = 'black', shape = 21, stroke = 0.2, offset = 0, show.legend = FALSE) + 
  geom_fruit(geom = geom_point, mapping = aes(size = hwi_norm), fill = hwi_colour, colour = 'black', shape = 21, stroke = 0.2, offset = 0.13, show.legend = FALSE) + 
  geom_fruit(geom = geom_point, mapping = aes(size = mass_norm), fill = mass_colour, colour = 'black', shape = 21, stroke = 0.2, offset = 0.15, show.legend = FALSE) + 
  geom_tiplab(size=2, aes(label=ebird_species_name_clean, color = mean_relative_abundance_proxy), offset = 15) +
  labs(color = "Mean relative abundance proxy") + 
  theme(legend.position = "bottom") + ggplot2::xlim(0, 80)

ggsave(filename(FIGURES_OUTPUT_DIR, 'phylogeny.jpg'), width = 2000, height = 2100, units = 'px')

Plot traits against abundance proxy

cut_off_3 = 50
cut_off_2 = 35
cut_off_1 = 1

hwi_by_mass_urban_3 = species_urban_response %>% filter(mean_relative_abundance_proxy > cut_off_3) %>% slice(chull(hwi, mass))
hwi_by_mass_urban_2 = species_urban_response %>% filter(mean_relative_abundance_proxy > cut_off_2) %>% slice(chull(hwi, mass))
hwi_by_mass_urban_1 = species_urban_response %>% filter(mean_relative_abundance_proxy > cut_off_1) %>% slice(chull(hwi, mass))

beak_width_by_mass_urban_3 = species_urban_response %>% filter(mean_relative_abundance_proxy > cut_off_3) %>% slice(chull(beak_width, mass))
beak_width_by_mass_urban_2 = species_urban_response %>% filter(mean_relative_abundance_proxy > cut_off_2) %>% slice(chull(beak_width, mass))
beak_width_by_mass_urban_1 = species_urban_response %>% filter(mean_relative_abundance_proxy > cut_off_1) %>% slice(chull(beak_width, mass))

hwi_by_beak_width_urban_3 = species_urban_response %>% filter(mean_relative_abundance_proxy > cut_off_3) %>% slice(chull(hwi, beak_width))
hwi_by_beak_width_urban_2 = species_urban_response %>% filter(mean_relative_abundance_proxy > cut_off_2) %>% slice(chull(hwi, beak_width))
hwi_by_beak_width_urban_1 = species_urban_response %>% filter(mean_relative_abundance_proxy > cut_off_1) %>% slice(chull(hwi, beak_width))

species_urban_response %>% filter(mean_relative_abundance_proxy > cut_off_3) %>% nrow()
[1] 5
species_urban_response %>% filter(mean_relative_abundance_proxy > cut_off_2) %>% nrow()
[1] 15
species_urban_response %>% filter(mean_relative_abundance_proxy > cut_off_1) %>% nrow()
[1] 72
polygon_line_type = 'dashed'
polygon_linewidth = 0.4
polygon_alpha1 = 0.05
polygon_alpha2 = 0.1
polygon_alpha3 = 0.15

hwi_by_mass = ggplot(species_urban_response, aes(x = hwi, y = mass, colour = mean_relative_abundance_proxy)) + 
  geom_polygon(data = hwi_by_mass_urban_1, alpha = polygon_alpha1, color = trait_polygon_light, fill = trait_polygon_light, linewidth = polygon_linewidth, linetype = polygon_line_type) +
  geom_polygon(data = hwi_by_mass_urban_2, alpha = polygon_alpha2, color = trait_polygon_med, fill = trait_polygon_med, linewidth = polygon_linewidth, linetype = polygon_line_type) +
  geom_polygon(data = hwi_by_mass_urban_3, alpha = polygon_alpha3, color = trait_polygon_dark, fill = trait_polygon_dark, linewidth = polygon_linewidth, linetype = polygon_line_type) +
  geom_point() + 
  abundance_proxy_scale +
  labs(colour = "Mean relative abundance proxy", y = 'Mass', x = '') + 
  theme(legend.position = 'bottom', legend.title.position = 'top', legend.key.width = unit(12, 'mm'))

beak_width_by_mass = ggplot(species_urban_response, aes(x = beak_width, y = mass, colour = mean_relative_abundance_proxy)) + 
  geom_polygon(data = beak_width_by_mass_urban_1, alpha = polygon_alpha1, color = trait_polygon_light, fill = trait_polygon_light, linewidth = polygon_linewidth, linetype = polygon_line_type) +
  geom_polygon(data = beak_width_by_mass_urban_2, alpha = polygon_alpha2, color = trait_polygon_med, fill = trait_polygon_med, linewidth = polygon_linewidth, linetype = polygon_line_type) +
  geom_polygon(data = beak_width_by_mass_urban_3, alpha = polygon_alpha3, color = trait_polygon_dark, fill = trait_polygon_dark, linewidth = polygon_linewidth, linetype = polygon_line_type) +
  geom_point() + 
  abundance_proxy_scale + 
  labs(y = '', x = 'Beak width')

hwi_by_beak_width = ggplot(species_urban_response, aes(x = hwi, y = beak_width, colour = mean_relative_abundance_proxy)) + 
  geom_polygon(data = hwi_by_beak_width_urban_1, alpha = polygon_alpha1, color = trait_polygon_light, fill = trait_polygon_light, linewidth = polygon_linewidth, linetype = polygon_line_type) +
  geom_polygon(data = hwi_by_beak_width_urban_2, alpha = polygon_alpha2, color = trait_polygon_med, fill = trait_polygon_med, linewidth = polygon_linewidth, linetype = polygon_line_type) +
  geom_polygon(data = hwi_by_beak_width_urban_3, alpha = polygon_alpha3, color = trait_polygon_dark, fill = trait_polygon_dark, linewidth = polygon_linewidth, linetype = polygon_line_type) +
  geom_point() + 
  abundance_proxy_scale + 
  labs(y = 'Beak width', x = 'HWI')

legend <- ggpubr::get_legend(
  # create some space to the left of the legend
  hwi_by_mass
)

plot_grid(
  nrow = 2, ncol = 2,
  hwi_by_mass + theme(legend.position="none"),
  beak_width_by_mass + theme(legend.position="none"),
  hwi_by_beak_width + theme(legend.position="none"),
  legend
)


ggsave(filename(FIGURES_OUTPUT_DIR, 'traits.jpg'), width = 2000, height = 1800, units = 'px')

LS0tCnRpdGxlOiAiQ29tcGFyZSB1cmJhbiB0cmFpdHMgYW5kIHBoeWxvZ2VuY3kiCm91dHB1dDogaHRtbF9ub3RlYm9vawpiaWJsaW9ncmFwaHk6IC4uL3JlZi5iaWIgIAotLS0KCmBgYHtyfQpzb3VyY2UoJy4uL2Vudi5SJykKYGBgCiMgQ3JlYXRlIGRhdGFzZXQKCkxvYWQgY29tbXVuaXR5IGRhdGEKYGBge3J9CmNvbW11bml0aWVzID0gcmVhZF9jc3YoZmlsZW5hbWUoQ09NTVVOSVRZX09VVFBVVF9ESVIsICdjb21tdW5pdGllc19mb3JfYW5hbHlzaXMuY3N2JykpCmNvbW11bml0aWVzCmBgYAoKTG9hZCB0cmFpdCBkYXRhCmBgYHtyfQp0cmFpdHMgPSByZWFkX2NzdihmaWxlbmFtZShUQVhPTk9NWV9PVVRQVVRfRElSLCAndHJhaXRzX2ViaXJkLmNzdicpKQpoZWFkKHRyYWl0cykKYGBgCgpgYGB7cn0Kc3BlY2llc191cmJhbl9yZXNwb25zZSA9IGNvbW11bml0aWVzICU+JSBncm91cF9ieShlYmlyZF9zcGVjaWVzX25hbWUpICU+JSBzdW1tYXJpc2UobWVhbl9yZWxhdGl2ZV9hYnVuZGFuY2VfcHJveHkgPSBtZWFuKHJlbGF0aXZlX2FidW5kYW5jZV9wcm94eSkpICU+JSBsZWZ0X2pvaW4odHJhaXRzKQpzcGVjaWVzX3VyYmFuX3Jlc3BvbnNlJGlzX3VyYmFuID0gc3BlY2llc191cmJhbl9yZXNwb25zZSRtZWFuX3JlbGF0aXZlX2FidW5kYW5jZV9wcm94eSA+IDAKc3BlY2llc191cmJhbl9yZXNwb25zZSRlYmlyZF9zcGVjaWVzX25hbWUgPSBzdHJfcmVwbGFjZShzcGVjaWVzX3VyYmFuX3Jlc3BvbnNlJGViaXJkX3NwZWNpZXNfbmFtZSwnICcsICdfJykKc3BlY2llc191cmJhbl9yZXNwb25zZQpgYGAKCiMjIE1vc3QgdXJiYW4gc3BlY2llcwpgYGB7cn0Kc3BlY2llc191cmJhbl9yZXNwb25zZSAlPiUgZmlsdGVyKG1lYW5fcmVsYXRpdmVfYWJ1bmRhbmNlX3Byb3h5ID4gNTApCmBgYAoKYGBge3J9CnNwZWNpZXNfdXJiYW5fcmVzcG9uc2UgJT4lIGZpbHRlcihtZWFuX3JlbGF0aXZlX2FidW5kYW5jZV9wcm94eSA+IDQwKQpgYGAKCmBgYHtyfQpzcGVjaWVzX3VyYmFuX3Jlc3BvbnNlICU+JSBmaWx0ZXIobWVhbl9yZWxhdGl2ZV9hYnVuZGFuY2VfcHJveHkgPiAzMCkKYGBgCgojIyBEaWZmZXJlbmNlIGFtb25nc3QgdXJiYW4gYW5kIG5vbi11cmJhbgpgYGB7cn0Kc3BlY2llc191cmJhbl9yZXNwb25zZSAlPiUgZ3JvdXBfYnkoaXNfdXJiYW4pICU+JSBzdW1tYXJpc2UoCiAgbWVkaWFuX2JlYWtfd2lkdGggPSBtZWRpYW4oYmVha193aWR0aCksCiAgaXFyX2JlYWtfd2lkdGggPSBJUVIoYmVha193aWR0aCksCiAgCiAgbWVkaWFuX2h3aSA9IG1lZGlhbihod2kpLAogIGlxcl9od2kgPSBJUVIoaHdpKSwKICAKICBtZWRpYW5fbWFzcyA9IG1lZGlhbihtYXNzKSwKICBpcXJfbWFzcyA9IElRUihtYXNzKSwKICAKICBuID0gbigpCikKYGBgCgojIENvbXBhcmUgdHJhaXRzIGJldHdlZW4gdXJiYW4gYW5kIG5vbi11cmJhbiBzcGVjaWVzCgojIyBHYXBlIFdpZHRoCmBgYHtyfQpnZ3Bsb3Qoc3BlY2llc191cmJhbl9yZXNwb25zZSwgYWVzKHggPSBpc191cmJhbiwgeSA9IGJlYWtfd2lkdGgpKSArIGdlb21fYm94cGxvdCgpCmBgYAoKYGBge3J9CndpbGNveC50ZXN0KGJlYWtfd2lkdGggfiBpc191cmJhbiwgc3BlY2llc191cmJhbl9yZXNwb25zZSkKYGBgClRoZXJlIGlzIG5vdCBhIHNpZ25pZmljYW50IHJlc3BvbnNlIGZvciB0aGUgZ2FwZSB3aWR0aCBiZXR3ZWVuIHVyYmFuIHNwZWNpZXMgYW5kIG5vbiB1cmJhbiBzcGVjaWVzLgoKIyMgSFdJCmBgYHtyfQpnZ3Bsb3Qoc3BlY2llc191cmJhbl9yZXNwb25zZSwgYWVzKHggPSBpc191cmJhbiwgeSA9IGh3aSkpICsgZ2VvbV9ib3hwbG90KCkKYGBgCgpgYGB7cn0Kd2lsY294LnRlc3QoaHdpIH4gaXNfdXJiYW4sIHNwZWNpZXNfdXJiYW5fcmVzcG9uc2UpCmBgYApUaGVyZSBpcyBhIHNpZ25pZmljYW50IHJlc3BvbnNlIGJldHdlZW4gdXJiYW4gYW5kIG5vbi11cmJhbiBzcGVjaWVzCgojIyBNYXNzCgpgYGB7cn0KZ2dwbG90KHNwZWNpZXNfdXJiYW5fcmVzcG9uc2UsIGFlcyh4ID0gaXNfdXJiYW4sIHkgPSBtYXNzKSkgKyBnZW9tX2JveHBsb3QoKQpgYGAKCmBgYHtyfQp3aWxjb3gudGVzdChtYXNzIH4gaXNfdXJiYW4sIHNwZWNpZXNfdXJiYW5fcmVzcG9uc2UpCmBgYAoKVGhlcmUgaXMgbm90IGEgc2lnbmlmaWNhbnQgcmVzcG9uc2UgYmV0d2VlbiBzcGVjaWVzLgoKIyBQaHlsb2dlbnkKCiMjIFBoeWxvZ2VudGljIHJlc3BvbnNlIHRvIHJlbGF0aXZlIGFidW5kYW5jZT8KYGBge3J9CnRyZWUgPSByZWFkLnRyZWUoZmlsZW5hbWUoVEFYT05PTVlfT1VUUFVUX0RJUiwgJ3BoeWxvZ2VueS50cmUnKSkKdHJlZV9wcnVuZWQgPSBsYWRkZXJpemUoZHJvcC50aXAodHJlZSwgc2V0ZGlmZih0cmVlJHRpcC5sYWJlbCwgc3BlY2llc191cmJhbl9yZXNwb25zZSRlYmlyZF9zcGVjaWVzX25hbWUpKSkKZ2d0cmVlKHRyZWVfcHJ1bmVkLCBsYXlvdXQ9ImZhbiIpCmBgYAoKYGBge3J9CmNvbHVtYmlkYWVfcmVzcG9uc2UgPC0gc3BlY2llc191cmJhbl9yZXNwb25zZSRtZWFuX3JlbGF0aXZlX2FidW5kYW5jZV9wcm94eQpuYW1lcyhjb2x1bWJpZGFlX3Jlc3BvbnNlKSA8LSBzcGVjaWVzX3VyYmFuX3Jlc3BvbnNlJGViaXJkX3NwZWNpZXNfbmFtZQpgYGAKCklzIHRoZSBhIHBoeWxvZ2VuZXRpYyBzaWduYWwgZm9yIG91ciByZWxhdGl2ZSBhYnVuZGFuY2UgcHJveHkKYGBge3J9CmNvbF91dF9waHlsb19zaWduYWwgPC0gcGh5bG9zaWcodHJlZV9wcnVuZWQsIGNvbHVtYmlkYWVfcmVzcG9uc2UsIG1ldGhvZD0ibGFtYmRhIiwgdGVzdD1UUlVFKQpjb2xfdXRfcGh5bG9fc2lnbmFsCmBgYAoKIyMgUGxvdCB0cmVlCmBgYHtyfQpzcGVjaWVzX3VyYmFuX3Jlc3BvbnNlJGViaXJkX3NwZWNpZXNfbmFtZV9jbGVhbiA9IGdzdWIoIl8iLCAiICIsIHNwZWNpZXNfdXJiYW5fcmVzcG9uc2UkZWJpcmRfc3BlY2llc19uYW1lKQoKbm9ybWFsaXplIDwtIGZ1bmN0aW9uKHgpICh4IC0gbWluKHgpKSAvIChtYXgoeCkgLSBtaW4oeCkpICogNSArIDEgICMgU2NhbGUgdG8gcmFuZ2UgWzEsIDZdCnNwZWNpZXNfdXJiYW5fcmVzcG9uc2UkYmVha193aWR0aF9ub3JtIDwtIG5vcm1hbGl6ZShzcGVjaWVzX3VyYmFuX3Jlc3BvbnNlJGJlYWtfd2lkdGgpCnNwZWNpZXNfdXJiYW5fcmVzcG9uc2UkaHdpX25vcm0gPC0gbm9ybWFsaXplKHNwZWNpZXNfdXJiYW5fcmVzcG9uc2UkaHdpKQpzcGVjaWVzX3VyYmFuX3Jlc3BvbnNlJG1hc3Nfbm9ybSA8LSBub3JtYWxpemUoc3BlY2llc191cmJhbl9yZXNwb25zZSRtYXNzKQoKZyA9IGdndHJlZSh0cmVlX3BydW5lZCwgbGF5b3V0PSJmYW4iKSAlPCslIHNwZWNpZXNfdXJiYW5fcmVzcG9uc2UgKyBhYnVuZGFuY2VfcHJveHlfc2NhbGUKZyArIAogIGdlb21fZnJ1aXQoZ2VvbSA9IGdlb21fcG9pbnQsIG1hcHBpbmcgPSBhZXMoc2l6ZSA9IGJlYWtfd2lkdGhfbm9ybSksIGZpbGwgPSBiZWFrX3dpZHRoX2NvbG91ciwgY29sb3VyID0gJ2JsYWNrJywgc2hhcGUgPSAyMSwgc3Ryb2tlID0gMC4yLCBvZmZzZXQgPSAwLCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArIAogIGdlb21fZnJ1aXQoZ2VvbSA9IGdlb21fcG9pbnQsIG1hcHBpbmcgPSBhZXMoc2l6ZSA9IGh3aV9ub3JtKSwgZmlsbCA9IGh3aV9jb2xvdXIsIGNvbG91ciA9ICdibGFjaycsIHNoYXBlID0gMjEsIHN0cm9rZSA9IDAuMiwgb2Zmc2V0ID0gMC4xMywgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKyAKICBnZW9tX2ZydWl0KGdlb20gPSBnZW9tX3BvaW50LCBtYXBwaW5nID0gYWVzKHNpemUgPSBtYXNzX25vcm0pLCBmaWxsID0gbWFzc19jb2xvdXIsIGNvbG91ciA9ICdibGFjaycsIHNoYXBlID0gMjEsIHN0cm9rZSA9IDAuMiwgb2Zmc2V0ID0gMC4xNSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKyAKICBnZW9tX3RpcGxhYihzaXplPTIsIGFlcyhsYWJlbD1lYmlyZF9zcGVjaWVzX25hbWVfY2xlYW4sIGNvbG9yID0gbWVhbl9yZWxhdGl2ZV9hYnVuZGFuY2VfcHJveHkpLCBvZmZzZXQgPSAxNSkgKwogIGxhYnMoY29sb3IgPSAiTWVhbiByZWxhdGl2ZSBhYnVuZGFuY2UgcHJveHkiKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArIGdncGxvdDI6OnhsaW0oMCwgODApCgpnZ3NhdmUoZmlsZW5hbWUoRklHVVJFU19PVVRQVVRfRElSLCAncGh5bG9nZW55LmpwZycpLCB3aWR0aCA9IDIwMDAsIGhlaWdodCA9IDIxMDAsIHVuaXRzID0gJ3B4JykKYGBgCgojIyBQbG90IHRyYWl0cyBhZ2FpbnN0IGFidW5kYW5jZSBwcm94eQpgYGB7cn0KY3V0X29mZl8zID0gNTAKY3V0X29mZl8yID0gMzUKY3V0X29mZl8xID0gMQoKaHdpX2J5X21hc3NfdXJiYW5fMyA9IHNwZWNpZXNfdXJiYW5fcmVzcG9uc2UgJT4lIGZpbHRlcihtZWFuX3JlbGF0aXZlX2FidW5kYW5jZV9wcm94eSA+IGN1dF9vZmZfMykgJT4lIHNsaWNlKGNodWxsKGh3aSwgbWFzcykpCmh3aV9ieV9tYXNzX3VyYmFuXzIgPSBzcGVjaWVzX3VyYmFuX3Jlc3BvbnNlICU+JSBmaWx0ZXIobWVhbl9yZWxhdGl2ZV9hYnVuZGFuY2VfcHJveHkgPiBjdXRfb2ZmXzIpICU+JSBzbGljZShjaHVsbChod2ksIG1hc3MpKQpod2lfYnlfbWFzc191cmJhbl8xID0gc3BlY2llc191cmJhbl9yZXNwb25zZSAlPiUgZmlsdGVyKG1lYW5fcmVsYXRpdmVfYWJ1bmRhbmNlX3Byb3h5ID4gY3V0X29mZl8xKSAlPiUgc2xpY2UoY2h1bGwoaHdpLCBtYXNzKSkKCmJlYWtfd2lkdGhfYnlfbWFzc191cmJhbl8zID0gc3BlY2llc191cmJhbl9yZXNwb25zZSAlPiUgZmlsdGVyKG1lYW5fcmVsYXRpdmVfYWJ1bmRhbmNlX3Byb3h5ID4gY3V0X29mZl8zKSAlPiUgc2xpY2UoY2h1bGwoYmVha193aWR0aCwgbWFzcykpCmJlYWtfd2lkdGhfYnlfbWFzc191cmJhbl8yID0gc3BlY2llc191cmJhbl9yZXNwb25zZSAlPiUgZmlsdGVyKG1lYW5fcmVsYXRpdmVfYWJ1bmRhbmNlX3Byb3h5ID4gY3V0X29mZl8yKSAlPiUgc2xpY2UoY2h1bGwoYmVha193aWR0aCwgbWFzcykpCmJlYWtfd2lkdGhfYnlfbWFzc191cmJhbl8xID0gc3BlY2llc191cmJhbl9yZXNwb25zZSAlPiUgZmlsdGVyKG1lYW5fcmVsYXRpdmVfYWJ1bmRhbmNlX3Byb3h5ID4gY3V0X29mZl8xKSAlPiUgc2xpY2UoY2h1bGwoYmVha193aWR0aCwgbWFzcykpCgpod2lfYnlfYmVha193aWR0aF91cmJhbl8zID0gc3BlY2llc191cmJhbl9yZXNwb25zZSAlPiUgZmlsdGVyKG1lYW5fcmVsYXRpdmVfYWJ1bmRhbmNlX3Byb3h5ID4gY3V0X29mZl8zKSAlPiUgc2xpY2UoY2h1bGwoaHdpLCBiZWFrX3dpZHRoKSkKaHdpX2J5X2JlYWtfd2lkdGhfdXJiYW5fMiA9IHNwZWNpZXNfdXJiYW5fcmVzcG9uc2UgJT4lIGZpbHRlcihtZWFuX3JlbGF0aXZlX2FidW5kYW5jZV9wcm94eSA+IGN1dF9vZmZfMikgJT4lIHNsaWNlKGNodWxsKGh3aSwgYmVha193aWR0aCkpCmh3aV9ieV9iZWFrX3dpZHRoX3VyYmFuXzEgPSBzcGVjaWVzX3VyYmFuX3Jlc3BvbnNlICU+JSBmaWx0ZXIobWVhbl9yZWxhdGl2ZV9hYnVuZGFuY2VfcHJveHkgPiBjdXRfb2ZmXzEpICU+JSBzbGljZShjaHVsbChod2ksIGJlYWtfd2lkdGgpKQoKc3BlY2llc191cmJhbl9yZXNwb25zZSAlPiUgZmlsdGVyKG1lYW5fcmVsYXRpdmVfYWJ1bmRhbmNlX3Byb3h5ID4gY3V0X29mZl8zKSAlPiUgbnJvdygpCnNwZWNpZXNfdXJiYW5fcmVzcG9uc2UgJT4lIGZpbHRlcihtZWFuX3JlbGF0aXZlX2FidW5kYW5jZV9wcm94eSA+IGN1dF9vZmZfMikgJT4lIG5yb3coKQpzcGVjaWVzX3VyYmFuX3Jlc3BvbnNlICU+JSBmaWx0ZXIobWVhbl9yZWxhdGl2ZV9hYnVuZGFuY2VfcHJveHkgPiBjdXRfb2ZmXzEpICU+JSBucm93KCkKYGBgCgpgYGB7cn0KcG9seWdvbl9saW5lX3R5cGUgPSAnZGFzaGVkJwpwb2x5Z29uX2xpbmV3aWR0aCA9IDAuNApwb2x5Z29uX2FscGhhMSA9IDAuMDUKcG9seWdvbl9hbHBoYTIgPSAwLjEKcG9seWdvbl9hbHBoYTMgPSAwLjE1Cgpod2lfYnlfbWFzcyA9IGdncGxvdChzcGVjaWVzX3VyYmFuX3Jlc3BvbnNlLCBhZXMoeCA9IGh3aSwgeSA9IG1hc3MsIGNvbG91ciA9IG1lYW5fcmVsYXRpdmVfYWJ1bmRhbmNlX3Byb3h5KSkgKyAKICBnZW9tX3BvbHlnb24oZGF0YSA9IGh3aV9ieV9tYXNzX3VyYmFuXzEsIGFscGhhID0gcG9seWdvbl9hbHBoYTEsIGNvbG9yID0gdHJhaXRfcG9seWdvbl9saWdodCwgZmlsbCA9IHRyYWl0X3BvbHlnb25fbGlnaHQsIGxpbmV3aWR0aCA9IHBvbHlnb25fbGluZXdpZHRoLCBsaW5ldHlwZSA9IHBvbHlnb25fbGluZV90eXBlKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSBod2lfYnlfbWFzc191cmJhbl8yLCBhbHBoYSA9IHBvbHlnb25fYWxwaGEyLCBjb2xvciA9IHRyYWl0X3BvbHlnb25fbWVkLCBmaWxsID0gdHJhaXRfcG9seWdvbl9tZWQsIGxpbmV3aWR0aCA9IHBvbHlnb25fbGluZXdpZHRoLCBsaW5ldHlwZSA9IHBvbHlnb25fbGluZV90eXBlKSArCiAgZ2VvbV9wb2x5Z29uKGRhdGEgPSBod2lfYnlfbWFzc191cmJhbl8zLCBhbHBoYSA9IHBvbHlnb25fYWxwaGEzLCBjb2xvciA9IHRyYWl0X3BvbHlnb25fZGFyaywgZmlsbCA9IHRyYWl0X3BvbHlnb25fZGFyaywgbGluZXdpZHRoID0gcG9seWdvbl9saW5ld2lkdGgsIGxpbmV0eXBlID0gcG9seWdvbl9saW5lX3R5cGUpICsKICBnZW9tX3BvaW50KCkgKyAKICBhYnVuZGFuY2VfcHJveHlfc2NhbGUgKwogIGxhYnMoY29sb3VyID0gIk1lYW4gcmVsYXRpdmUgYWJ1bmRhbmNlIHByb3h5IiwgeSA9ICdNYXNzJywgeCA9ICcnKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICdib3R0b20nLCBsZWdlbmQudGl0bGUucG9zaXRpb24gPSAndG9wJywgbGVnZW5kLmtleS53aWR0aCA9IHVuaXQoMTIsICdtbScpKQoKYmVha193aWR0aF9ieV9tYXNzID0gZ2dwbG90KHNwZWNpZXNfdXJiYW5fcmVzcG9uc2UsIGFlcyh4ID0gYmVha193aWR0aCwgeSA9IG1hc3MsIGNvbG91ciA9IG1lYW5fcmVsYXRpdmVfYWJ1bmRhbmNlX3Byb3h5KSkgKyAKICBnZW9tX3BvbHlnb24oZGF0YSA9IGJlYWtfd2lkdGhfYnlfbWFzc191cmJhbl8xLCBhbHBoYSA9IHBvbHlnb25fYWxwaGExLCBjb2xvciA9IHRyYWl0X3BvbHlnb25fbGlnaHQsIGZpbGwgPSB0cmFpdF9wb2x5Z29uX2xpZ2h0LCBsaW5ld2lkdGggPSBwb2x5Z29uX2xpbmV3aWR0aCwgbGluZXR5cGUgPSBwb2x5Z29uX2xpbmVfdHlwZSkgKwogIGdlb21fcG9seWdvbihkYXRhID0gYmVha193aWR0aF9ieV9tYXNzX3VyYmFuXzIsIGFscGhhID0gcG9seWdvbl9hbHBoYTIsIGNvbG9yID0gdHJhaXRfcG9seWdvbl9tZWQsIGZpbGwgPSB0cmFpdF9wb2x5Z29uX21lZCwgbGluZXdpZHRoID0gcG9seWdvbl9saW5ld2lkdGgsIGxpbmV0eXBlID0gcG9seWdvbl9saW5lX3R5cGUpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IGJlYWtfd2lkdGhfYnlfbWFzc191cmJhbl8zLCBhbHBoYSA9IHBvbHlnb25fYWxwaGEzLCBjb2xvciA9IHRyYWl0X3BvbHlnb25fZGFyaywgZmlsbCA9IHRyYWl0X3BvbHlnb25fZGFyaywgbGluZXdpZHRoID0gcG9seWdvbl9saW5ld2lkdGgsIGxpbmV0eXBlID0gcG9seWdvbl9saW5lX3R5cGUpICsKICBnZW9tX3BvaW50KCkgKyAKICBhYnVuZGFuY2VfcHJveHlfc2NhbGUgKyAKICBsYWJzKHkgPSAnJywgeCA9ICdCZWFrIHdpZHRoJykKCmh3aV9ieV9iZWFrX3dpZHRoID0gZ2dwbG90KHNwZWNpZXNfdXJiYW5fcmVzcG9uc2UsIGFlcyh4ID0gaHdpLCB5ID0gYmVha193aWR0aCwgY29sb3VyID0gbWVhbl9yZWxhdGl2ZV9hYnVuZGFuY2VfcHJveHkpKSArIAogIGdlb21fcG9seWdvbihkYXRhID0gaHdpX2J5X2JlYWtfd2lkdGhfdXJiYW5fMSwgYWxwaGEgPSBwb2x5Z29uX2FscGhhMSwgY29sb3IgPSB0cmFpdF9wb2x5Z29uX2xpZ2h0LCBmaWxsID0gdHJhaXRfcG9seWdvbl9saWdodCwgbGluZXdpZHRoID0gcG9seWdvbl9saW5ld2lkdGgsIGxpbmV0eXBlID0gcG9seWdvbl9saW5lX3R5cGUpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IGh3aV9ieV9iZWFrX3dpZHRoX3VyYmFuXzIsIGFscGhhID0gcG9seWdvbl9hbHBoYTIsIGNvbG9yID0gdHJhaXRfcG9seWdvbl9tZWQsIGZpbGwgPSB0cmFpdF9wb2x5Z29uX21lZCwgbGluZXdpZHRoID0gcG9seWdvbl9saW5ld2lkdGgsIGxpbmV0eXBlID0gcG9seWdvbl9saW5lX3R5cGUpICsKICBnZW9tX3BvbHlnb24oZGF0YSA9IGh3aV9ieV9iZWFrX3dpZHRoX3VyYmFuXzMsIGFscGhhID0gcG9seWdvbl9hbHBoYTMsIGNvbG9yID0gdHJhaXRfcG9seWdvbl9kYXJrLCBmaWxsID0gdHJhaXRfcG9seWdvbl9kYXJrLCBsaW5ld2lkdGggPSBwb2x5Z29uX2xpbmV3aWR0aCwgbGluZXR5cGUgPSBwb2x5Z29uX2xpbmVfdHlwZSkgKwogIGdlb21fcG9pbnQoKSArIAogIGFidW5kYW5jZV9wcm94eV9zY2FsZSArIAogIGxhYnMoeSA9ICdCZWFrIHdpZHRoJywgeCA9ICdIV0knKQoKbGVnZW5kIDwtIGdncHVicjo6Z2V0X2xlZ2VuZCgKICAjIGNyZWF0ZSBzb21lIHNwYWNlIHRvIHRoZSBsZWZ0IG9mIHRoZSBsZWdlbmQKICBod2lfYnlfbWFzcwopCgpwbG90X2dyaWQoCiAgbnJvdyA9IDIsIG5jb2wgPSAyLAogIGh3aV9ieV9tYXNzICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIiksCiAgYmVha193aWR0aF9ieV9tYXNzICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIiksCiAgaHdpX2J5X2JlYWtfd2lkdGggKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSwKICBsZWdlbmQKKQoKZ2dzYXZlKGZpbGVuYW1lKEZJR1VSRVNfT1VUUFVUX0RJUiwgJ3RyYWl0cy5qcGcnKSwgd2lkdGggPSAyMDAwLCBoZWlnaHQgPSAxODAwLCB1bml0cyA9ICdweCcpCmBgYAo=